package br.com.abella.snippets.xpath;

import java.io.IOException;
import javax.xml.namespace.QName;
import javax.xml.parsers.*;
import javax.xml.xpath.*;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XPathReader {

	private String xmlFile;

	private Document xmlDocument;

	private XPath xPath;

	/**
	 * 
	 */
	public XPathReader() {

	}
	
	/**
	 * 
	 * @param xmlFile
	 */
	public XPathReader(String xmlFile) {
		this.xmlFile = xmlFile;
		initObjects();
	}

	/**
	 * 
	 */
	private void initObjects() {
		try {
			xmlDocument = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder().parse(xmlFile);
			xPath = XPathFactory.newInstance().newXPath();
		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (SAXException ex) {
			ex.printStackTrace();
		} catch (ParserConfigurationException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 
	 * @param expression
	 * @param returnType
	 * @return
	 */
	public Object read(String expression, QName returnType) {
		try {
			XPathExpression xPathExpression = xPath.compile(expression);
			return xPathExpression.evaluate(xmlDocument, returnType);
		} catch (XPathExpressionException ex) {
			ex.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 
	 */
	@Test
	public void test(){
        
        XPathReader reader = new XPathReader("src/main/resources/projects.xml");
        
        // To get a xml attribute.
        String expression = "/projects/project[1]/@id";
        System.out.println(reader.read(expression, 
		XPathConstants.STRING) + "\n");
        
        // To get a child element's value.'
        expression = "/projects/project[2]/name";
        System.out.println(reader.read(expression, XPathConstants.STRING) + "\n");
        
        // To get an entire node
        expression = "/projects/project[3]";
        NodeList thirdProject = (NodeList)reader.read(expression, XPathConstants.NODESET);
        traverse(thirdProject);
    }

	/**
	 * 
	 * @param rootNode
	 */
	private static void traverse(NodeList rootNode) {
		
		for (int index = 0; index < rootNode.getLength(); index++) {
			
			Node aNode = rootNode.item(index);
			if (aNode.getNodeType() == Node.ELEMENT_NODE) {
				NodeList childNodes = aNode.getChildNodes();
				if (childNodes.getLength() > 0) {
					System.out.println("Node Name-->" + aNode.getNodeName()
							+ " , Node Value-->" + aNode.getTextContent());
				}
				traverse(aNode.getChildNodes());
			}
		}
	}	
}